package vip.xiaonuo.smzq.modular.lifecycle.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import org.locationtech.jts.geom.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import vip.xiaonuo.smzq.core.utils.GeometryUtil;
import vip.xiaonuo.smzq.core.utils.TransFormUtil;
import vip.xiaonuo.smzq.modular.lifecycle.service.module.CommonService;
import vip.xiaonuo.smzq.modular.lifecycle.service.module.LifeCycleDataManagerService;
import vip.xiaonuo.smzq.modular.lifecycle.vo.PolygonWgs84V0;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class CoordinateTranUtil {

    @Resource
    HutoolExtend hutoolExtend;

    @Autowired
    CommonService commonService;
    /**
     * 转换成wkt3的坐标字符串
     * @param coordinateStr 坐标字符串
     * @return
     */
    public PolygonWgs84V0 coordinateDisposeWKT3(String coordinateStr){
        PolygonWgs84V0 result = null;

        try {
            result = polygonCoorTranWgs84(coordinateStr);
//            result = TransFormUtil.CoordinateDisposeWKT3(coordinateStr);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }


    /**
     *
     * @param coordinatesStr
     * @return
     */
    private PolygonWgs84V0 polygonCoorTranWgs84(String coordinatesStr){
        PolygonWgs84V0 result = new PolygonWgs84V0();
        try {
            String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
            //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
            Integer analysisType = TransFormUtil.polygonAnalysis_type(new String[]{coordinatesArry[3], coordinatesArry[4]});
            //面的个数
            Integer polygonNum = Integer.parseInt(coordinatesArry[0]);
            //第一个面的点个数
            Integer pointNum = Integer.parseInt(coordinatesArry[1]);
            //第一个X点
            Integer x = 3;
            //第一个Y点
            Integer y = 4;
            //存放多个面
            List<Polygon> multiPolygonList = new ArrayList<>();
            //存放为洞的面
            List<Polygon> holePolygonList = new ArrayList<>();
            for (int i = 0; i < polygonNum; i++) {
                Coordinate[] coordinates = new Coordinate[pointNum];
                for (int j = 0; j < pointNum; j++, x += 3, y += 3) {
                    //x点
                    String lon = coordinatesArry[x];
                    //y点
                    String lat = coordinatesArry[y];
                    //转为点
                    Point point = TransFormUtil.polygonAnalysis_point(new String[]{lon, lat}, analysisType);
                    coordinates[j] = point.getCoordinate();
                }
                //创建面
                Polygon polygon = GeometryUtil.createPolygon(coordinates);
                //判断是多面或带洞的面
                Integer type = Integer.parseInt(coordinatesArry[y + 1]);
                if (type == -1) {
                    holePolygonList.add(polygon);
                } else {
                    multiPolygonList.add(polygon);
                }
                if (i < polygonNum - 1) {
                    //第二个或更多面的点数
                    pointNum = Integer.parseInt(coordinatesArry[y + 2]);
                    x += 5;
                    y += 5;
                }
            }

            MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(multiPolygonList.toArray(new Polygon[multiPolygonList.size()]));
            MultiPolygon holePolygon = GeometryUtil.createMultiPolygon(holePolygonList.toArray(new Polygon[holePolygonList.size()]));
            //存在带洞的情况
            if (holePolygonList.size() != 0) {
                List<LinearRing> linearRingList = holePolygonList.stream().map(Polygon::getExteriorRing).collect(Collectors.toList());
                //创建带洞的面
                Coordinate[] coordinates = multiPolygon.getCoordinates();
                GeometryFactory geometryFactory = new GeometryFactory();
                LinearRing ring = geometryFactory.createLinearRing(coordinates);
                if(!StrUtil.contains(Convert.toStr(ring),"EMPTY")){
                    Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(ring, linearRingList.toArray(new LinearRing[holePolygonList.size()]));
                    multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygonWithHoles});
                }
            }
            //检查图形的有效性
//        if (!multiPolygon.isValid()) {
//            return null;
//        }
            if(CollUtil.size(multiPolygonList)!=0){
                result.setMultiPolygon(multiPolygon.toString());
                result.setMultiPolygonRings(commonService.getMutiPointXY(multiPolygon.toString()));
            }
            if(CollUtil.size(holePolygonList)!=0){
                result.setHolePolygon(holePolygon.toString());
                result.setHolePolygonRings(commonService.getMutiPointXY(holePolygon.toString()));
            }
//            return multiPolygon.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }


        return result;
    }

    /**
     * 判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
     * @param coordinatesStr 坐标
     * @return
     */
    public Integer getAnalysisType(String coordinatesStr){
        String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = TransFormUtil.polygonAnalysis_type(new String[]{coordinatesArry[3], coordinatesArry[4]});
        return analysisType;
    }

    public Point tranToWgs84Point(Integer analysisType,String x,String y){
        Point point = TransFormUtil.polygonAnalysis_point(new String[]{y, x}, analysisType);
        return point;
    }

    /**
     * 检查并创建点
     * @param x
     * @param y
     * @return
     */
    public Point checkCreatePoint(String x, String y){
        if(ObjUtil.isEmpty(x) || ObjUtil.isEmpty(y)){
            return null;
        }
        if (!(NumberUtil.isNumber(x) && NumberUtil.isNumber(y))) {
            return null;
        }

        Integer analysisType = TransFormUtil.polygonAnalysis_type(new String[]{x, y});
        Point point = TransFormUtil.polygonAnalysis_point(new String[]{x, y}, analysisType);
        return point;
    }

    /**
     * 得到84 xy坐标集合
     * @return
     */
    public List<Double> get84Coordinates(String x, String y){
        List<Double> result = CollUtil.newArrayList();
        if(ObjUtil.isNotEmpty(x) && ObjUtil.isNotEmpty(y)){
            x = Convert.toStr(new BigDecimal(x));
            y = Convert.toStr(new BigDecimal(y));

            Point point = checkCreatePoint(x,y);
            if(ObjUtil.isNotNull(point)){
                result.add(point.getCoordinates()[0].getX());
                result.add(point.getCoordinates()[0].getY());
            }else{
                result.add(0D);
                result.add(0D);
            }

        }
        return result;
    }

    /**
     * 度分秒转wgs84坐标
     * @return
     */
    public double dmsToWgs84(double coor){

//        度
        Double degree = getDegree(coor);
//        分
        Double m = getMorS(coor, "分");

        Double s = getMorS(coor,"秒");

        return degree+m/60+s/3600;

    }

    /**
     * 得到度
     * @param coor 度分秒的坐标
     * @return
     */
    public Double getDegree(double coor){
        return Convert.toDouble(StrUtil.split(Convert.toStr(coor),".").get(0));
    }

    /**
     * 得到分或秒
     * @param coor 度分秒的坐标
     * @param type 分/秒
      */

    public Double getMorS(double coor,String type){
        List<String> list = StrUtil.split(Convert.toStr(coor),".");
        if(CollUtil.size(list)>1){
            String msStr = CollUtil.getLast(list);
            if(StrUtil.equals(type,"分")){
                Double m = Convert.toDouble(StrUtil.sub(msStr,0,2));
                return m==null?0:m;
            }else{
                String sStr = StrUtil.sub(msStr,2,StrUtil.length(msStr));
                if(StrUtil.length(sStr)>2){
                    sStr = hutoolExtend.inertStr(sStr,".",2);
                }
                Double s = Convert.toDouble(sStr);
                return s==null?0:s;
            }
        }else {
            return 0D;
        }
    }

}
